基本推导过程是，将函数调用的参数类型与函数模板相应的类型参数进行比较，并尝试对推导出的一个或多个参数类型进行替换。每个参数对都进行独立分析，若最后得出的结论不同，则推导失败。看看下面的例子:
 
\begin{lstlisting}[style=styleCXX]
template<typename T>
T max (T a, T b)
{
	return b < a ? a : b;
}

auto g = max(1, 1.0);
\end{lstlisting} 
 
第一个调用参数是int类型，因此初始max()模板的参数T试探性地推导为int类型。然而，第二个调用参数是double，因此对于这个参数T应该是double型参数:这与前面的结论冲突。这里说的是“推导失败”，而不是“程序无效”。毕竟，对于另一个名为max的模板，推导可能会成功(函数模板可以像普通函数一样重载;请参阅第1.5节和第16章)。
 
若推导出的所有模板参数结论一致，那么若在函数声明的其余部分中替换参数导致无效构造，推导过程仍可能失败。例如:

\begin{lstlisting}[style=styleCXX]
template<typename T>
typename T::ElementT at (T a, int i)
{
	return a[i];
}

void f (int* p)
{
	int x = at(p, 7);
}
\end{lstlisting} 

这里T推断为int*(只有一种参数类型出现了T，因此显然没有分析冲突)。但在返回类型T::ElementT中用int*替换T显然无效，所以推导失败。

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}这种情况下，推导失败会导致错误。但这属于SFINAE(参见第8.4节):如果另一个函数推导成功，代码可能是有效的。
\end{tcolorbox}

继续探索参数匹配是如何进行的。我们将其描述为匹配类型A(从调用参数类型派生)到参数化类型P(从调用参数声明派生)。若调用参数是用引用声明符声明的，P为引用的类型，A是具体的参数类型。但在其他情况下，P是声明的参数类型，而A是通过(忽略const和volatile限定符)将数组和函数类型衰变为指针类型。

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}衰变是指函数和数组类型隐式转换为指针类型的术语。
\end{tcolorbox}

例如:

\begin{lstlisting}[style=styleCXX]
template<typename T> void f(T); // parameterized type P is T
template<typename T> void g(T&); // parameterized type P is also T

double arr[20];
int const seven = 7;

f(arr); // nonreference parameter: T is double*
g(arr); // reference parameter: T is double[20]
f(seven); // nonreference parameter: T is int
g(seven); // reference parameter: T is int const
f(7); // nonreference parameter: T is int
g(7); // reference parameter: T is int => ERROR: can’t pass 7 to int&
\end{lstlisting} 

对于调用f(arr)，arr的数组类型衰变为double*类型，这是T的类型。f(7)中去掉了const限定，因此T推导为int。相反，调用g(x)可以将T推导为double[20]类型(没有发生衰变)。类似地，g(7)的左值参数类型为int const，在匹配引用参数时不删除const和volatile限定符，因此T推导为int const。但注意g(7)会推导T为int(非类右值表达式没有const或volatile限定类型)，并且调用会失败，因为7不能传递给int\&类型的参数。

当参数是字符串字面值时，绑定到引用的参数不会发生衰变。重新考虑用引用声明的max()模板:

\begin{lstlisting}[style=styleCXX]
template<typename T>
T const& max(T const& a, T const& b);
\end{lstlisting} 

可以合理地预期，对于表达式max(“Apple”，“Pie”)，T推导为char const*。然而，“Apple”的类型是char const[6]，而“Pie”的类型是char const[4]。没有发生数组到指针的衰变(推导涉及到引用参数)，因此T必须同时是char[6]和char[4]，才能推导成功，但这是不可能的。参见第7.4节关于如何处理这种情况的讨论。























 